package org.esti.model;

import org.hibernate.validator.constraints.Email;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.Date;

/**
 * @author Artem Loginov (logart)
 */

/**
 * Contain information about user
 */
@Entity
@Table(name = "users")
public class User {

    private static final int MIN_NAME_WIDTH = 2;
    private static final int MAX_NAME_WIDTH = 40;
    private static final int MIN_PASSWORD_WIDTH = 6;
    private static final int MAX_PASSWORD_WIDTH = 40;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Size(min = MIN_NAME_WIDTH, max = MAX_NAME_WIDTH, message = "Login must contain more than 2 and less than 40 characters.")
    @Pattern(regexp = "[A-Za-z0-9\\.-]+", message = "Login must contain only latin symbols, number, \".\" or -")
    private String login;

    @Size(min = MIN_PASSWORD_WIDTH, max = MAX_PASSWORD_WIDTH, message = "Password must contain more than 6 and less than 40 characters.")
    private String password;

    @Size(min = MIN_NAME_WIDTH, max = MAX_NAME_WIDTH, message = "Name must contain more than 2 and less than 40 characters.")
    private String name;

    @Column(name = "middle_name")
    private String middleName;

    @Size(min = MIN_NAME_WIDTH, max = MAX_NAME_WIDTH, message = "Surname must contain more than 2 and less than 40 characters.")
    private String surname;

    @NotNull
    @Enumerated(EnumType.STRING)
    private UserRoles role = UserRoles.ROLE_USER;

    @DateTimeFormat(style = "S-")
    @Past
    @NotNull(message = "Birthday must be defined.")
    @Temporal(value = TemporalType.DATE)
    private Date birthday;

    @Email(message = "This e-mail is invalid.")
    private String email;

    @NotNull(message = "You professional level must be defined.")
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "level_id")
    private Level level;

    private String avatar = "/resources/img/default_avatar.jpg";

    private boolean locked;

    public long getId() {
        return id;
    }

    public String getLogin() {
        return login;
    }

    public String getPassword() {
        return password;
    }

    public String getName() {
        return name;
    }

    public String getMiddleName() {
        return middleName;
    }

    public String getSurname() {
        return surname;
    }

    /**
     * returns surname and name divided by space
     *
     * @return surname and name divided by space
     */
    public String getShortFullName() {
        return name + " " + surname;
    }

    /**
     * returns surname, name and middle name divided by space
     *
     * @return surname, name and middle name divided by space
     */
    public String getLongFullName() {
        return surname + " " + name + " " + middleName;
    }

    public Date getBirthday() {
        return birthday;
    }

    public String getEmail() {
        return email;
    }

    public Level getLevel() {
        return level;
    }

    public String getAvatar() {
        return avatar;
    }

    public boolean isLocked() {
        return locked;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public void setBirthday(Date bithday) {
        this.birthday = bithday;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setLevel(Level level) {
        this.level = level;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public void setLocked(boolean locked) {
        this.locked = locked;
    }

    public void setRole(UserRoles role) {
        this.role = role;
    }

    public UserRoles getRole() {
        return role;
    }
}